#!/usr/bin/perl

use strict;

package main;

my $worker = Worker->worker();
$worker->doAction();
$worker->prHeader();

my $html = Html->html();
$html->tmpl( $worker->getWorkerList(), $worker->getGenderList() );

exit();

package Worker;

use DBI;
use CGI;

sub worker 
{
  my $class = shift;
  my $self = {};
  bless $self, $class;
  $self->_init(@_);
  return $self;
}

sub _init 
{
  my $self = shift;
  $self->{_DBH} = DBI->connect("DBI:Pg:dbname=test", "postgres", "info", 
    {RaiseError => 1, AutoCommit => 1});
  $self->{_CGI} = CGI->new();
  $self->{data} = { $self->{_CGI}->Vars };
}

sub cgi 
{
  my $self = shift;
  return $self->{_CGI};
}

sub prHeader
{
  my $self = shift;
  print $self->cgi->header(-charset=>'windows-1251');
}

sub dbh 
{
  my $self = shift;
  return $self->{_DBH};
}

# редактирование записи
sub doAction 
{
  my $self = shift;
  my $data = $self->{data};
  if ($data->{add} or $data->{save}) 
  {
    # вставка пустой записи
    if ($data->{add}) 
    {
      $self->dbh->do(q{INSERT INTO worker(name) VALUES('')});
      return;
    }
    # сохранение
    if ($data->{save}) 
    {
      # разбор управляющих параметров
      for my $key ( keys %{$data}) 
      {
        if ( $key =~ /^update_(\d+)$/ ) 
        {
          push @{$data->{to_change}}, $1;
        } 
        elsif ( $key =~ /^delete_(\d+)$/ ) 
        {
          push @{$data->{to_delete}}, $1;
        }
      }
      # обновление
      my $query = " UPDATE worker SET name = ?, gen = ? WHERE id = ? ";
      for my $upd ( @{$data->{to_change}} ) 
      {
        $self->dbh->do($query, undef, $data->{'name_'.$upd}, 
                         $data->{'gen_'.$upd}, $upd);
      }
      # удаление
      $query = " DELETE FROM worker WHERE id = ? ";
      for my $del ( @{$data->{to_delete}} ) 
      {
        $self->dbh->do($query, undef, $del);
      }
    }
  }
}

sub getWorkerList 
{
  my $self = shift;
  my $data = $self->dbh->selectall_arrayref(q{
    SELECT id, name, gen FROM worker 
    ORDER BY id DESC 
  }, {Columns=>{}});
  return $data ? $data : [];
=comment
  return [ {id => 1, name => 'Лосев Борис',    gen => 2},
           {id => 2, name => 'Шарапова Арина', gen => 1} ];
=cut
}

sub getGenderList 
{
  my $self = shift;
  my $data = $self->dbh->selectall_arrayref(q{
    SELECT id, name FROM gender 
    ORDER BY id DESC 
  }, {Columns=>{}});
  return $data ? $data : [];
=comment
  return [ {id => 1, name => 'Женский'}, 
           {id => 2, name => 'Мужской'} ];
=cut
}

DESTROY 
{
  my $self = shift;
  $self->dbh->disconnect();
}

package Html;

use Template;

sub html 
{
  my $class = shift;
  return bless {}, $class;
}

# обработка и печать шаблона
sub tmpl 
{
  my $self = shift;
  my ($worker, $gen) = @_;

  my $tt = Template->new()
    or die $Template::ERROR, "\n";

  $tt->process(\*DATA, {worker=>$worker, gender=>$gen})
    or die $tt->error(), "\n";
}

__END__

[% INCLUDE head %] 
  [% FOREACH item = worker %] [% INCLUDE middle %] [% END %]
[% INCLUDE bottom %]

[% BLOCK head %]
<form action="/cgi-bin/tender.1.pl" method="post" name="list">
<table cellspacing="1" cellpadding="1" border="1" align="left" width="1%">
  <tr>
    <td width="1%" align="center">#</td>
    <td width="100%" align="center">Имя</td>
    <td width="30" align="center">Пол</td>
    <td width="30" align="center">Изм</td>
    <td width="30" align="center">Удл</td>
  </tr>
[% END %]

[% BLOCK middle %]
  <tr>
    <td align="center">[%item.id%]</td>
    <td><input type="text" name="name_[%item.id%]" value="[%item.name%]" size="40"></td>
    <td>
       <select name="gen_[%item.id%]">
         [%- INCLUDE option id => item.gen -%]
       </select>
    </td>
    <td><input type="checkbox" name="update_[%item.id%]" value="1"></td>
    <td><input type="checkbox" name="delete_[%item.id%]" value="1"></td>
    </td>
  </tr>
[% END %]

[% BLOCK option %]
  [%- FOREACH item = gender %]
    <option value=[% item.id %][% IF id == item.id %] selected[% END %]> [% item.name -%]
  [% END %]
[% END %]

[% BLOCK bottom %]
  <tr>
    <td colspan="5" align="center">
      <input type="submit" name="add" value="Добавить"> &nbsp; | &nbsp;
      <input type="submit" name="save" value="Сохранить">
    </td>
  </tr>
</table>
</form>
[% END %]

